using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.IO;
using System.Net;
using Microsoft.WindowsLive.Id.Client;
using System.Windows.Forms;

namespace LiveUtils
{
    class SpacesAdapter
    {
        private const string SPACES_API_URL = "https://storage.msn.com/storageservice/MetaWeblog.rpc";
        private const string requestXml = "<?xml version=\"1.0\" encoding=\"utf-8\"?><methodCall><methodName>metaWeblog.newPost</methodName><params><param><value><string>{0}</string></value></param><param><value><string>{1}</string></value></param><param><value><string>{2}</string></value></param><param><value><struct><member><name>title</name><value><string>{3}</string></value></member><member><name>link</name><value><string /></value></member><member><name>description</name><value><string>{4}</string></value></member><member><name>categories</name><value><array><data /></array></value></member></struct></value></param><param><value><boolean>1</boolean></value></param></params></methodCall>";
        private const string blogImagesUrl = "http://storage.msn.com/MyData/myspace/spacefolder/photoalbums/Blog%20Images/";
        private const int httpTimeout = 10000;

        Identity oID = null;

        public SpacesAdapter(Identity oID)
        {
            if(oID == null)
            {
                throw new Exception("null oId passed to SpacesAdapter");
            }

            this.oID = oID;
        }

        public bool PostBlog(string subject, string body, string spaceUrl)
        {
            byte[] postData = new UTF8Encoding(false).GetBytes(String.Format(requestXml, "MyBlog", spaceUrl, "", subject, body));
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(SPACES_API_URL);
            string ticket = GetStorageTicket();

            if(ticket == null)
            {
                return false;
            }

            request.Headers.Add("Authorization", "WLID1.0 " + ticket);
            request.AllowAutoRedirect = false;
            request.UserAgent = "WindowLiveClientSDKSpacesLoginTester";
            request.ContentType = "text/xml";
            request.Pipelined = false;
            request.ProtocolVersion = HttpVersion.Version10;
            request.Method = "POST";
            request.Timeout = httpTimeout;

            using (Stream requestStream = request.GetRequestStream())
            {
                requestStream.Write(postData, 0, postData.Length);
            }

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            if (response.StatusCode == HttpStatusCode.OK)
            {
                // Check the response for a fault
                string responseBody = "";
                const int bufSize = 1024;
                byte[] buf = new byte[bufSize];
                int nbytes;

                while ((nbytes = response.GetResponseStream().Read(buf, 0, bufSize)) > 0)
                {
                    responseBody += Encoding.ASCII.GetString(buf, 0, nbytes);
                }

                if (responseBody.ToLower().Contains("fault"))
                {
                    MessageBox.Show("Fault when posting to blog: " + responseBody);
                    return false;
                }

                return true;
            }
            else
            {
                return false;
            }
        }

        private string GetStorageTicket()
        {
            string ticket = null;

            try
            {
                /* HANDS ON LAB: SECTION C -- POSTING TO A USER'S BLOG
                 * Uncomment the line of code to get the ticket.
                 */
                //ticket = oID.GetTicket("storage.msn.com", "MBI", true);
            }
            catch (WLLogOnException wlex)
            {
                //Check to see if FlowUrl is defined.
                if (wlex.FlowUrl != null)
                {
                    //If FlowUrl is defined, direct user to the web page to correct the error.
                    MessageBox.Show(wlex.ErrorString + "Please go to " + wlex.FlowUrl.AbsoluteUri + "to correct the condition that caused the error");
                }
                else
                {
                    //If FlowUrl is not defined, simply display the ErrorString.
                    MessageBox.Show(wlex.ErrorString);
                }
            }

            return ticket;
        }

        public bool CreateBlogImagesFolder()
        {
            string ticket = GetStorageTicket();

            if (ticket == null)
                return false;

            try
            {
                string imageUrl = blogImagesUrl;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(imageUrl);
               
                request.Method = "MKCOL";
                request.Headers["Authorization"] = "WLID1.0 " + ticket;
                request.Timeout = httpTimeout;
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();

                if (response.StatusCode == HttpStatusCode.Created)
                {
                    return true;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.ToString());
            }

            return false;
        }

        public string UploadImage(string filename, Image image)
        {
            string ticket = GetStorageTicket();

            if (ticket == null)
            {
                return null;
            }

            try
            {
                string imageUrl = blogImagesUrl + filename;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(imageUrl);

                request.Method = "PUT";
                request.Headers["Authorization"] = "WLID1.0 " + ticket;
                request.Timeout = 5000;

                image.Save(request.GetRequestStream(), System.Drawing.Imaging.ImageFormat.Jpeg);
                request.GetRequestStream().Close();

                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                HttpStatusCode status = response.StatusCode;

                if (status == HttpStatusCode.Created || status == HttpStatusCode.NoContent)
                {
                    // The location parameter in the header contians the url of the image that is
                    // visible to everyone.
                    return response.Headers["Location"];
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            return null;
        }
    }
}
